/*
 * UserSession.java
 *
 * Created on 28 de Junho de 2005, 22:29
 */

package jhub;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import jhub.dao.DAOFactory;
import jhub.text.*;
import jhub.users.Operator;
import jhub.users.User;
import org.apache.log4j.Category;
import org.apache.log4j.Logger;

/**
 *
 * @author  botelhodaniel
 */
public class UserSession extends DCChannel{
        
    public static Logger logger = Logger.getLogger(DCChannel.class);
    
    private int sessionID;
    private Date start;
    private Date end;
    private HubSession hubSession;
    private User user;
    private SupportsMessage supportsMessage;
    private VersionMessage versionMessage;
    private MyINFOMessage myInfoMessage;
    

    public UserSession(HubSession hubSession,Socket socket) throws IOException, ClassNotFoundException, SQLException {
        super(socket);
        this.hubSession = hubSession;
        setStart(new Date());
        DAOFactory.getUserSessionDAO().startUserSession(this);
    } 
    
    public DCRawCommand read() throws IOException{
        DCRawCommand raw = super.read();
        try {
            DAOFactory.getMessageDAO().addMessage(this,raw,"USER");
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return raw;
    }
    
    protected int write(DCRawCommand raw) throws UnsupportedEncodingException, IOException{
        logger.info("<"+new SimpleDateFormat("yyyy-MM-dd kk:mm:ss").format(raw.getTimeStamp())+">(U:"+((this.getUser()==null)?"<no-nick>":this.getUser().getNick())+"["+this.getIp()+":"+this.getPort()+"],H->U:"+raw+")");
        
        //try{
        int bytes = super.write(raw);
        /*}catch(IOException ex){
            
        } */
        try {
            DAOFactory.getMessageDAO().addMessage(this,raw,"HUB");
        } catch (SQLException ex) {
            ex.printStackTrace();
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return bytes;
    }

    public VersionMessage getVersionMessage() {
        return versionMessage;
    }

    public void setVersionMessage(VersionMessage versionMessage) {
        parse(versionMessage);
        this.versionMessage = versionMessage;
    }

    public MyINFOMessage getMyInfoMessage() {
        return myInfoMessage;
    }

    public void setMyInfoMessage(MyINFOMessage myInfoMessage) {
        parse(myInfoMessage);
        this.myInfoMessage = myInfoMessage;
    }
    
    private void parse(VersionMessage versionMessage){
        user.setVersion(versionMessage.getVersion());
    }
    
    private void parse(MyINFOMessage myInfo){

        user.setNick(myInfo.getNick());
        user.setDescription(myInfo.getDescription());
        user.setSharesize(myInfo.getSharesize());
        user.setSpeed(myInfo.getSpeed());
        user.setEmail(myInfo.getEmail());
        
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
        try {
            DAOFactory.getUserSessionDAO().update(this);
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
 

    public int writeMyInfoMessage(MyINFOMessage message) throws UnsupportedEncodingException, IOException{
        return write(message);
    }

    public int writeHello() throws ParseException, UnsupportedEncodingException, IOException{
        return write(HelloMessage.getInstance(user.getNick()));
    }

    public int writePrivateChatMessage(PrivateChatMessage msg) throws UnsupportedEncodingException, IOException {
        return write(msg);
    }

    public int writePublicChatMessage(PublicChatMessage pubChat) throws UnsupportedEncodingException, IOException {
        return write(pubChat);
    }

    public int writeConnectToMeMessage(ConnectToMeMessage conn) throws UnsupportedEncodingException, IOException {
        return write(conn);
    }

    public int writeGetOpList(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException {
        return write(dCRawCommand);
    }

    public int writeGetNickList(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException{
        return write(dCRawCommand);
    }

    public int writeRawCommand(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException{
        return write(dCRawCommand);
    }

    public int writeLock(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException{
        return write(dCRawCommand);
    }

    public int writeHubName(HubNameMessage hubNameMessage) throws UnsupportedEncodingException, IOException{
        return write(hubNameMessage);
    }

    public int writeMTOD(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException{
        return write(dCRawCommand);
    }

    public int writeGetPasswd(DCRawCommand dCRawCommand) throws UnsupportedEncodingException, IOException{
        return write(dCRawCommand);
    }

    public SupportsMessage getSupportsMessage() {
        return supportsMessage;
    }

    public void setSupportsMessage(SupportsMessage supportsMessage) {
        this.supportsMessage = supportsMessage;
    }

    public int writeValidateDenide() throws UnsupportedEncodingException, IOException, ParseException {
        return write(ValidateDenideMessage.getInstance());
    }

    public int writeBadPass() throws UnsupportedEncodingException, IOException, ParseException {
        return write(BadPassMessage.getInstance());
    }

    public int writeForceMove(OpForceMoveMessage opForceMoveMessage)  throws UnsupportedEncodingException, IOException, ParseException{
        return write(opForceMoveMessage);
    }

    public HubSession getHubSession() {
        return hubSession;
    }

    public int getSessionID() {
        return sessionID;
    }

    public void setSessionID(int sessionID) {
        this.sessionID = sessionID;
    }

    public Date getStart() {
        return start;
    }

    public void setStart(Date start) {
        this.start = start;
    }

    public Date getEnd() {
        return end;
    }

    public void setEnd(Date end) {
        this.end = end;
        try {
            DAOFactory.getUserSessionDAO().update(this);
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }

    public int writeHubRuntimeSpecs() throws UnsupportedEncodingException, IOException, ParseException {
        
        long diff = this.getStart().getTime() - this.getHubSession().getStartDate().getTime();
        
        return write(new DCRawCommand("<jDC> This Hub is running jDC Hub library version 2k7070614 (UpTime: "+(diff / (1000 * 60 ))+" minutes)"));
    }

    public int writepassiveSearchResultMessage(PassiveSearchResultMessage passiveSearchResultMessage) throws UnsupportedEncodingException, IOException, ParseException {
        return write(passiveSearchResultMessage.getReplyCommand());
    }

    public int writeWarningMessage(String string) throws UnsupportedEncodingException, IOException {
        return write(new DCRawCommand("<HubWarning> "+string));
    }
    
}
